
using System;


namespace Framework
{
    public abstract class BaseComponent : Event.EventDispatcher, IReference, IDisposable 
    {
        public static bool CheckIsFromPool(Type type)
        {
            return (bool)type.GetPropertyRecursion("IsFromPool").GetValue(null);
        }

        public static bool IsFromPool
        { 
            get
            {
                return true;
            }
        }

        public static T CreateComponent<T>() where T : BaseComponent
        {
            T component;
            if (CheckIsFromPool(typeof(T)))
            {
                component = ReferencePool.Fetch<T>();
            }
            else
            {
                component = (T)Activator.CreateInstance(typeof(T));
            }
            return component;
        }

        public bool IsDisposed { get; private set; } = false;

        public BaseComponent Parent { get; set; }

        public T GetParent<T>() where T : class 
        { 
            return this.Parent as T;
        }

        protected BaseComponent()
        {
            this.IsDisposed = false;
            this.Init();
        }

        public virtual int Priority
        {
            get
            {
                return 0;
            }
        }

        public virtual bool NeedUpdate
        {
            get
            {
                return false;
            }
        }

        public virtual void Update(float elapseSeconds, float realElapseSeconds)
        {
        }

        public virtual void Dispose()
        {
            if (this.IsDisposed)
            {
                return;
            }
            this.IsDisposed = true;
            this.Parent = null;
            if (CheckIsFromPool(this.GetType()))
            {
                ReferencePool.Recycle(this);
            }
            this.OnDispose();
        }

        public virtual void OnDispose()
        {
        }

        public virtual void OnFetch()
        {
            this.IsDisposed = false;
            this.Init();
        }

        public virtual void OnRecycle()
        {
        }

        public virtual void Init()
        {
        }
    }
}